package cn.hd01.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import cn.hd01.common.BaseConstant.IsBalance;
import cn.hd01.common.BaseConstant.RebateSummaryType;
import cn.hd01.common.IntegrationRuleCode;
import cn.hd01.export.result.ImportResult;
import cn.hd01.repository.COrderRepository;
import cn.hd01.repository.entity.COrder;
import cn.hd01.repository.entity.COrderPayment;
import cn.hd01.repository.entity.Customer;
import cn.hd01.repository.entity.Dictionary;
import cn.hd01.repository.entity.DistributorDetails;
import cn.hd01.repository.entity.DistributorLevel;
import cn.hd01.repository.entity.IntegrationRuleBook;
import cn.hd01.repository.entity.OrderProduct;
import cn.hd01.repository.entity.RebateBook;
import cn.hd01.repository.entity.RebateSummary;
import cn.hd01.repository.entity.User;
import cn.hd01.service.COrderPaymentService;
import cn.hd01.service.COrderService;
import cn.hd01.service.CustomerService;
import cn.hd01.service.DictionaryService;
import cn.hd01.service.DistributorDetailsService;
import cn.hd01.service.DistributorLevelService;
import cn.hd01.service.IntegrationRuleBookService;
import cn.hd01.service.OrderProductService;
import cn.hd01.service.RebateBookService;
import cn.hd01.service.RebateSummaryService;
import cn.hd01.service.UserService;
import cn.hd01.sms.SmsService;
import cn.hd01.util.DictionaryType;
import cn.hd01.web.util.WebException;

@Service
public class COrderServiceImpl extends BaseServiceImpl<COrder, Integer> implements COrderService {

	private COrderRepository repository;
	
	@Autowired
	private COrderPaymentService cOrderPaymentService;
	
	@Autowired
	private CustomerService customerService;
	
	@Autowired
	private DistributorLevelService distributorLevelService;
	
	@Autowired
	private DictionaryService dictionaryService;
	
	@Autowired
	private RebateSummaryService rebateSummaryService;
	
	@Autowired
	private RebateBookService rebateBookService;

	@Autowired
	private UserService userService;
	
	@Autowired
	private IntegrationRuleBookService integrationRuleBookService;

	@Autowired
	private SmsService smsService;
	
	@Autowired
	private COrderPaymentService cOrderpaymentService;
	
	@Autowired
	private DistributorDetailsService distributorDetailsService;
	
	@Autowired
	private EntityManager em;
	
	@Autowired
	private OrderProductService orderProductService;
	
	@Autowired
	public COrderServiceImpl(COrderRepository repository) {
		super(repository);
		this.repository = repository;
	}

	@Override
	public Page<COrder> findAll(final COrder order, Pageable pageable) {
		Page<COrder> result = null; 
		if (order == null) {
			result = repository.findAll(pageable);;
		}

		result = repository.findAll(Specifications.where(new Specification<COrder>() {
			@Override
			public Predicate toPredicate(Root<COrder> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				return buildPredicate(r, q, cb, order);
			}
		}), pageable);
		
		List<COrder> list = result.getContent();
		for(COrder o : list){
			BigDecimal amount = o.getAmount();
			BigDecimal[] amountArr = cOrderPaymentService.findAllAmount(o.getId());
			
			BigDecimal receivedAmount = (amountArr == null || amountArr[0] == null) ? BigDecimal.ZERO : amountArr[0];
			BigDecimal feeAmount = (amountArr == null || amountArr[1] == null) ? BigDecimal.ZERO : amountArr[1];
			BigDecimal balanceAmount = (amountArr == null || amountArr[2] == null) ? BigDecimal.ZERO : amountArr[2];
			BigDecimal unBalanceAmount = (amountArr == null || amountArr[3] == null) ? BigDecimal.ZERO : amountArr[3];
			
			o.setReceivedAmount(receivedAmount);
			if(amount.compareTo(receivedAmount) < 0){
				o.setLeftAmount(BigDecimal.ZERO);
			}else{
				o.setLeftAmount(o.getAmount().subtract(receivedAmount));
			}
			
			o.setFeeAmount(feeAmount);
			o.setBalanceAmount(balanceAmount);
			o.setUnBalanceAmount(unBalanceAmount);
			
			DistributorDetails details = distributorDetailsService.findByDistributorId(o.getDistributorId());
			if(details != null){
				o.setDistributorShopName(details.getShopName());
			}
			
			List<OrderProduct> orderList = orderProductService.findByOrderId(o.getId());
			StringBuffer count = new StringBuffer();
			if(!CollectionUtils.isEmpty(orderList)){
				for(OrderProduct op : orderList){
					count.append(op.getProductName()).append("(").append(op.getOperationCount()).append("),");
				}
			}
			
			o.setProductNameAndCount(count.length() > 0 ? count.substring(0, count.length() - 1) : "");
		}
		
		return result;
	}
	
	private Predicate buildPredicate(Root<COrder> r, CriteriaQuery<?> q, CriteriaBuilder cb, COrder order){
		List<Predicate> predicates = new ArrayList<Predicate>();

		if(StringUtils.hasText(order.getCustomerName())){
			predicates.add(cb.like(r.get("customerName").as(String.class), "%" + order.getCustomerName() + "%"));
		}
		
		if(StringUtils.hasText(order.getDistributorName())){
			Join<RebateSummary, DistributorDetails> join = r.join("distributorDetails", JoinType.LEFT);
			predicates.add(cb.or(cb.like(join.get("shopName").as(String.class), "%" + order.getDistributorName() + "%"),
					cb.like(r.get("distributorName").as(String.class), "%" + order.getDistributorName() + "%")));
			//predicates.add(cb.like(join.get("shopName").as(String.class), order.getDistributorName() + "%"));
			//predicates.add(cb.like(r.get("distributorName").as(String.class), "%" + order.getDistributorName() + "%"));
		}
		
		if(StringUtils.hasText(order.getCustomerPhoneNo())){
			predicates.add(cb.like(r.get("customerPhoneNo").as(String.class), "%" + order.getCustomerPhoneNo() + "%"));
		}
		
		if(StringUtils.hasText(order.getDistributorPhoneNo())){
			predicates.add(cb.like(r.get("distributorPhoneNo").as(String.class), "%" + order.getDistributorPhoneNo() + "%"));
		}
		
		if(order.getRecommDistributorId() != null){
			predicates.add(cb.equal(r.get("recommDistributorId").as(Integer.class), order.getRecommDistributorId()));
		}
		
		if(StringUtils.hasText(order.getIsBalance()) && !"-1".equals(order.getIsBalance())){
			predicates.add(cb.equal(r.get("isBalance").as(String.class), order.getIsBalance()));
		}
		
		if(order.getCustomerId() != null){
			predicates.add(cb.equal(r.get("customerId").as(Integer.class), order.getCustomerId()));
		}
		
		if(order.getDistributorId() != null){
			predicates.add(cb.equal(r.get("distributorId").as(Integer.class), order.getDistributorId()));
		}
		
		if (StringUtils.hasText(order.getBeginDate())) {
			predicates.add(cb.greaterThanOrEqualTo(r.get("createTime").as(String.class), order.getBeginDate()));
		}
		
		if (StringUtils.hasText(order.getEndDate())) {
			predicates.add(cb.lessThanOrEqualTo(r.get("createTime").as(String.class), order.getEndDate()));
		}
		
		if(!CollectionUtils.isEmpty(order.getDistributorIdList())){
			predicates.add(r.get("distributorId").in(order.getDistributorIdList()));
		}
		
		return cb.and(predicates.toArray(new Predicate[] {}));
	}

	@Override
	public COrder fillCOrder(COrder order, ImportResult result, List<DistributorLevel> levelList) {
		
		Customer customer = customerService.findByPhoneNo(order.getCustomerPhoneNo());
		Customer distributor = customerService.findByPhoneNo(order.getDistributorPhoneNo());
		Customer recommDistributor = null;
		if(distributor.getRecommendDistributorId() != null){
			recommDistributor = customerService.findOne(distributor.getRecommendDistributorId());	
		}
		
		String errorText = "";
		
		if(order.getAmount() == null){
			errorText = "存在金额不合法，请校验！";
			throw new WebException(HttpStatus.BAD_REQUEST, "存在金额不合法，请校验！");
		}
		
		if(customer == null){
			errorText = "不存在此客户电话号码：" + order.getCustomerPhoneNo() + ", 导入失败";
			result.setMsg(errorText);
			throw new WebException(HttpStatus.BAD_REQUEST, "不存在此客户电话号码：" + order.getCustomerPhoneNo() + ", 导入失败");
		}
		
		order.setCustomerId(customer.getId());
		order.setCustomerName(customer.getName());
		order.setDistributorId(distributor == null ? null : distributor.getId());
		order.setDistributorName(distributor == null ? null : distributor.getName());
		order.setIsBalance(IsBalance.BALANCE_WAIT);
		
		Date date = new Date();
		order.setUpdateTime(date);
		order.setCreateTime(date);
		order.setDistributorRebate(BigDecimal.ZERO);
		order.setServantRebate(BigDecimal.ZERO);
		
		DistributorLevel level = null;
		if(distributor != null){
			level = findLevel(errorText, result, distributor.getLevelId(), levelList);
			
			order.setDistributorRebateRate(level.getRebateRate());
			order.setDistributorRebate(order.getAmount().multiply(order.getDistributorRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
			
			//服务老师设置与佣金
			if(distributor.getServantId() != null){
				User servantTeacher = userService.findOne(distributor.getServantId());
				
				if(servantTeacher != null){
					order.setServantId(servantTeacher.getId());
					order.setServantName(servantTeacher.getName());
				}
				
				List<Dictionary> dictList = dictionaryService.findByType(DictionaryType.SERVANT_REBATE_RATE);
				Dictionary servantDict = null;
				if(!CollectionUtils.isEmpty(dictList)){
				    servantDict = dictList.get(0);
				    
				    order.setServantRebateRate(new BigDecimal(servantDict.getValue()));
					order.setServantRebate(order.getAmount().multiply(order.getServantRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
				}
				
			}
			
		}
		
		//推荐渠道商佣金
		if(recommDistributor != null ){
			order.setRecommDistributorId(recommDistributor.getRecommendDistributorId());
			order.setRecommDistributorName(recommDistributor.getName());
			order.setRecommDistributorPhoneNo(recommDistributor.getRecommendDistributorPhoneNo());
			
			
			List<Dictionary> dictList = dictionaryService.findByType(DictionaryType.DISTRIBUTOR_REBATE_RATE);
			if(!CollectionUtils.isEmpty(dictList)){
				Dictionary dict = dictList.get(0);
				
				//推荐渠道商佣金
				BigDecimal rate = new BigDecimal(dict.getValue().trim());
				
				order.setRecommDistributorRebateRate(rate);
				order.setRecommDistributorRebate(order.getAmount().multiply(rate).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
			}
			
		}
		
		return order;
	}
	
	private DistributorLevel findLevel(String errorText, ImportResult result, Integer levelId, List<DistributorLevel> levelList){
		for(DistributorLevel l : levelList){
			if(levelId == l.getId()){
				return l;
			}
		}

		errorText = "不存在渠道商权益，id为" + levelId + ", 导入失败";
		result.setMsg(errorText);
		throw new WebException(HttpStatus.BAD_REQUEST, "不存在渠道商权益，id为" + levelId + ", 导入失败");
	}

	@Override
	public void balanceOrder(Integer id) {
		COrder order = repository.findOne(id);
		if(order == null){
			throw new WebException(HttpStatus.BAD_REQUEST, "订单不存在");
		}else if(order.getDistributorId() == null || order.getAmount() == null){
			throw new WebException(HttpStatus.BAD_REQUEST, "订单数据异常");
		}
		
		repository.balanceOrder(IsBalance.BALANCE_DOWN, id);
		
		Integer customerId = order.getCustomerId();
		String projectName = order.getProjectName();
		
		//渠道商结算佣金
		if(order.getDistributorId() != null){
			balanceDistributor(order.getDistributorId(), order.getDistributorName(), order.getDistributorRebate(), projectName);
		}
		
		//推荐渠道商结算佣金
		if(order.getRecommDistributorId() != null){
			balanceDistributor(order.getRecommDistributorId(), order.getRecommDistributorName(), order.getRecommDistributorRebate(), projectName);
		}
		
		//服务老师结算佣金
		if(order.getServantId() != null){
			RebateSummary trs = rebateSummaryService.findByRefIdAndType(order.getServantId(), RebateSummaryType.SERVANT_TEACHER);
			
			if(trs == null){
				User servant = userService.findOne(order.getServantId());
				trs = new RebateSummary();
				trs.setAllRebate(order.getServantRebate());
				trs.setAllWaitWithdrawRebate(BigDecimal.ZERO);
				trs.setAllWithdrawRebate(order.getServantRebate());
				Date date = new Date();
				trs.setCreateTime(date);
				trs.setUpdateTime(date);
				trs.setRefId(servant.getId());
				trs.setName(servant.getName());
				trs.setType(RebateSummaryType.SERVANT_TEACHER);
				rebateSummaryService.save(trs);
				
				//流水
				RebateBook book = new RebateBook();
				book.setRefId(order.getServantId());
				book.setName(servant.getName());
				book.setRebate(order.getServantRebate());
				book.setType(RebateSummaryType.SERVANT_TEACHER);
				book.setRebateReason(order.getProjectName());
				
				book.setCreateTime(date);
				book.setUpdateTime(date);
				book.setAllRebate(trs.getAllWaitWithdrawRebate());
				rebateBookService.save(book);
				
			}else{
				trs.setAllRebate(trs.getAllRebate().add(order.getServantRebate()));
				trs.setAllWaitWithdrawRebate(trs.getAllWaitWithdrawRebate().subtract(order.getServantRebate()));
				trs.setAllWithdrawRebate(trs.getAllWithdrawRebate().add(order.getServantRebate()));
				rebateSummaryService.save(trs);
			}
		}
		
		//客户结算消费积分
		IntegrationRuleBook consumeBook = new IntegrationRuleBook();
		consumeBook.setCustomerId(customerId);
		consumeBook.setCustomerName(order.getCustomerName());
		consumeBook.setAmount(order.getAmount());
		integrationRuleBookService.save(consumeBook, IntegrationRuleCode.CONSUME_INTEGRATION);
		
		//推荐客户结算推荐积分
		Integer recommCustomerId = customerService.findOne(customerId).getRecommendCustomerId();
		if(recommCustomerId != null){
			Customer recommCustomer = customerService.findOne(recommCustomerId);
			if(recommCustomer != null){
				IntegrationRuleBook recommBook = new IntegrationRuleBook();
				recommBook.setCustomerId(recommCustomerId);
				recommBook.setCustomerName(recommCustomer.getName());
				integrationRuleBookService.save(recommBook, IntegrationRuleCode.RECOMM_CONSUME_INTEGRATION);
			}
		}
		
		smsService.sendFixTimeMsg(order.getCustomerPhoneNo(), new StringBuffer(order.getCustomerName()).append(",").append("您的订单：消费项目为").append(order.getProjectName()).append("，金额为").append(order.getAmount()).append("订单录制成功。").toString());
		smsService.sendFixTimeMsg(order.getDistributorPhoneNo(), new StringBuffer(order.getDistributorName()).append(",").append("，您的订单：客户为").append(order.getCustomerName()).append("，消费项目为").append(order.getProjectName()).append("，金额为").append(order.getAmount()).append("千郡后台已经结算，佣金为").append(order.getDistributorRebate()).append("。").toString());
	}

	/**
	 * 结算渠道商
	 * @param distributorId
	 * @param rebate
	 */
	private void balanceDistributor(Integer distributorId, String distributorName, BigDecimal rebate, String projectName){
		
		Date date = new Date();

		//佣金汇总
		RebateSummary drs = rebateSummaryService.findByRefIdAndType(distributorId, RebateSummaryType.DISTRIBUTOR);
		if(drs == null){
			Customer distributor = customerService.findOne(distributorId);
			if(distributor != null){
				drs = new RebateSummary();
				drs.setAllRebate(rebate);
				drs.setAllWaitWithdrawRebate(BigDecimal.ZERO);
				drs.setAllWithdrawRebate(rebate);
				drs.setCreateTime(date);
				drs.setUpdateTime(date);
				drs.setRefId(distributor.getId());
				drs.setName(distributor.getName());
				drs.setType(RebateSummaryType.DISTRIBUTOR);
				rebateSummaryService.save(drs);
			}
		}else{
			//drs.setAllRebate(drs.getAllRebate().add(rebate));
			drs.setAllWaitWithdrawRebate(drs.getAllWaitWithdrawRebate().subtract(rebate));
			drs.setAllWithdrawRebate(drs.getAllWithdrawRebate().add(rebate));
			rebateSummaryService.save(drs);
		}
		
		//流水
		RebateBook book = new RebateBook();
		book.setRefId(distributorId);
		book.setName(distributorName);
		book.setRebate(rebate);
		book.setType(RebateSummaryType.DISTRIBUTOR);
				
		book.setCreateTime(date);
		book.setUpdateTime(date);
		book.setAllRebate(rebate.add(drs.getAllRebate()));
		book.setRebateReason(projectName);
		rebateBookService.save(book);
	}
	
	@Override
	public List<COrder> findAll(final COrder order) {
		if(order == null){
			return repository.findAll();
		}
		
		return repository.findAll(Specifications.where(new Specification<COrder>() {
			@Override
			public Predicate toPredicate(Root<COrder> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				return buildPredicate(r, q, cb, order);
			}
		}));
	}

	@Override
	public List<Object[]> findSummary(String beginDate, String endDate) {
		if(StringUtils.hasText(beginDate) && StringUtils.hasText(endDate)){
			return repository.findSummary(beginDate, endDate);
		}else if(StringUtils.hasText(beginDate)){
			return repository.findSummaryByBegin(beginDate);
		}else if(StringUtils.hasText(endDate)){
			return repository.findSummaryByEnd(endDate);
		}else{
			return repository.findSummary();
		}
	}

	@Override
	public Integer countByIsBalanceAndDistributorId(String isBalance,
			Integer distributorId) {
		return repository.countByIsBalanceAndDistributorId(isBalance, distributorId);
	}

	@Override
	public Integer countByIsBalance(String isBalance) {
		return repository.countByIsBalance(isBalance);
	}

	@Override
	public Integer countByServantIdAndIsBalance(Integer ServantId,
			String isBalance) {
		return repository.countByServantIdAndIsBalance(ServantId, isBalance);
	}

	@Override
	public Integer countOperationByMonth() {
		return repository.countOperationByMonth();
	}
	
	@Override
	public Integer countOperationByToday() {
		return repository.countOperationByToday();
	}

	@Override
	public Double sumAchievementToday() {
		return repository.sumAchievementToday();
	}
	
	@Override
	public Double sumAchievementMonth() {
		return repository.sumAchievementMonth();
	}

	@Override
	public Double progressMonthlyTarget() {
		return repository.progressMonthlyTarget();
	}

	@Override
	public Double sumDistributorRebateRate(String isBalance) {
		if(StringUtils.isEmpty(isBalance)){
			return repository.sumDistributorRebateRate();
		}else{
			return repository.sumDistributorRebateRate(isBalance);
		}
	}

	@Override
	public List<Object[]> findKValueGroupByDate(Integer distributorId) {
		return repository.findKValueGroupByDate(distributorId);
	}

	@Override
	public BigDecimal findCustomerSumAmount(Integer customerId) {
		BigDecimal sumAmount = repository.findCustomerSumAmount(customerId);
		return sumAmount == null ? BigDecimal.ZERO.setScale(2) : sumAmount;
	}

	@Override
	public void balanceOrder(Integer id, COrderPayment payment) {
		/*COrderPayment originPayment = null;
		if(payment.getId() != null){
			originPayment = cOrderpaymentService.findOne(payment.getId());
		}*/
		
		BigDecimal amount = payment.getAmount();
		BigDecimal balanceAmount = amount.subtract(payment.getFeeAmount());
		
		balanceAmount = balanceAmount.compareTo(BigDecimal.ZERO) > 0 ? balanceAmount : BigDecimal.ZERO;
		COrder order = repository.findOne(id);
		if(order == null){
			throw new WebException(HttpStatus.BAD_REQUEST, "订单不存在");
		}else if(order.getDistributorId() == null || order.getAmount() == null){
			throw new WebException(HttpStatus.BAD_REQUEST, "订单数据异常");
		}
		
		//repository.balanceOrder(IsBalance.BALANCE_DOWN, id);
		
		Integer customerId = order.getCustomerId();
		String projectName = order.getProjectName();
		
		//渠道商结算佣金
		BigDecimal distributorRebate = payment.getDistributorRebate();
		if(order.getDistributorId() != null){
			//balanceAmount.multiply(order.getDistributorRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
			/*if(originPayment != null && IsBalance.BALANCE_DOWN.equals(payment.getIsBalance())){
				BigDecimal originDistributorRebate = originPayment.getAmount().multiply(order.getDistributorRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
				distributorRebate = distributorRebate.subtract(originDistributorRebate);
				
			}*/
			payment.setDistributorRebate(distributorRebate);
			order.setDistributorRebate(order.getDistributorRebate().add(distributorRebate));
			balanceDistributor(order.getDistributorId(), order.getDistributorName(), distributorRebate, projectName);
		}
		
		//推荐渠道商结算佣金
		if(order.getRecommDistributorId() != null && -1 != order.getRecommDistributorId()){
			BigDecimal recommDistributorRebate = payment.getRecommDistributorRebate();//balanceAmount.multiply(order.getRecommDistributorRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
			/*if(originPayment != null && IsBalance.BALANCE_DOWN.equals(payment.getIsBalance())){
				BigDecimal originRecommDistributorRebate = originPayment.getAmount().multiply(order.getRecommDistributorRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
				recommDistributorRebate = recommDistributorRebate.subtract(originRecommDistributorRebate);
			}*/
			payment.setRecommDistributorRebate(recommDistributorRebate);
			balanceDistributor(order.getRecommDistributorId(), order.getRecommDistributorName(), recommDistributorRebate, projectName);
		}
		
		//服务老师结算佣金
		if(order.getServantId() != null){
			RebateSummary trs = rebateSummaryService.findByRefIdAndType(order.getServantId(), RebateSummaryType.SERVANT_TEACHER);
			
			BigDecimal servantRebate = balanceAmount.multiply(order.getServantRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
			/*if(originPayment != null && IsBalance.BALANCE_DOWN.equals(payment.getIsBalance())){
				BigDecimal originServantRebate = originPayment.getAmount().multiply(order.getServantRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
				servantRebate = servantRebate.subtract(originServantRebate);
			}*/
			order.setServantRebate(order.getServantRebate().add(servantRebate));
			if(trs == null){
				User servant = userService.findOne(order.getServantId());
				trs = new RebateSummary();
				
				trs.setAllRebate(servantRebate);
				trs.setAllWaitWithdrawRebate(BigDecimal.ZERO);
				trs.setAllWithdrawRebate(BigDecimal.ZERO);
				Date date = new Date();
				trs.setCreateTime(date);
				trs.setUpdateTime(date);
				trs.setRefId(servant.getId());
				trs.setName(servant.getName());
				trs.setType(RebateSummaryType.SERVANT_TEACHER);
				rebateSummaryService.save(trs);
				
				//流水
				RebateBook book = new RebateBook();
				book.setRefId(order.getServantId());
				book.setName(servant.getName());
				book.setRebate(order.getServantRebate());
				book.setType(RebateSummaryType.SERVANT_TEACHER);
				book.setRebateReason(order.getProjectName());
				
				book.setCreateTime(date);
				book.setUpdateTime(date);
				book.setAllRebate(trs.getAllWaitWithdrawRebate());
				rebateBookService.save(book);
				
			}else{
				trs.setAllRebate(trs.getAllRebate().add(servantRebate));
				rebateSummaryService.save(trs);
			}
		}
		
		//客户结算消费积分
		IntegrationRuleBook consumeBook = new IntegrationRuleBook();
		consumeBook.setCustomerId(customerId);
		consumeBook.setCustomerName(order.getCustomerName());
		consumeBook.setAmount(amount);
		/*if(originPayment != null && IsBalance.BALANCE_DOWN.equals(payment.getIsBalance())){
			consumeBook.setAmount(originPayment.getAmount().subtract(balanceAmount));
		}else{
			consumeBook.setAmount(balanceAmount);
		}*/
		IntegrationRuleBook book = integrationRuleBookService.save(consumeBook, IntegrationRuleCode.CONSUME_INTEGRATION);
		
		//尊贵的千郡顾客，您好！本次消费金额XXX元。本次获得XXX分，当前可用积分XX分。祝您生活愉快！
		
		
		
		//推荐客户结算推荐积分，只是在第一次的时候增加
		List<COrderPayment> list = cOrderpaymentService.findByOrderId(payment.getOrderId());
		if(list.size() == 0){
			Integer recommCustomerId = customerService.findOne(customerId).getRecommendCustomerId();
			if(recommCustomerId != null){
				Customer recommCustomer = customerService.findOne(recommCustomerId);
				if(recommCustomer != null){
					IntegrationRuleBook recommBook = new IntegrationRuleBook();
					recommBook.setCustomerId(recommCustomerId);
					recommBook.setCustomerName(recommCustomer.getName());
					integrationRuleBookService.save(recommBook, IntegrationRuleCode.RECOMM_CONSUME_INTEGRATION);
				}
			}
		}
		//【千郡医疗】温馨提示：尊敬合作伙伴，您本次产生XXX K值（客户XXX），详情可登录ID查询。如有任何疑问，请与相关负责人联系。祝您生活愉快！
		//smsService.sendFixTimeMsg(order.getDistributorPhoneNo(), new StringBuffer(order.getDistributorName()).append(",").append("，您的订单：客户为").append(order.getCustomerName()).append("，消费项目为").append(order.getProjectName()).append("，金额为").append(order.getAmount()).append("千郡后台已经结算，佣金为").append(order.getDistributorRebate()).append("。").toString());
		smsService.sendFixTimeMsg(order.getDistributorPhoneNo(), new StringBuffer("合作伙伴，您本次产生").append(distributorRebate).append("K值（客户").append(order.getCustomerName()).append("），详情可登录ID查询。如有任何疑问，请与相关负责人联系。祝您生活愉快！").toString());
	}

	@Override
	public Integer findBalanceKValue(Integer distributorId) {
		return repository.findBalanceKValue(distributorId);
	}

	@Override
	public Integer findUnBalanceKValue(Integer distributorId) {
		return repository.findUnBalanceKValue(distributorId);
	}

	@Override
	public COrder findByFinanceOrderNo(String financeOrderNo) {
		return repository.findByFinanceOrderNo(financeOrderNo);
	}
	
	private long total(COrder order) {
		
		//SELECT COUNT(1) FROM (SELECT 1 FROM  c_order o INNER JOIN c_order_payment p  ON o.id = p.order_id  WHERE distributor_id = 100  AND o.recomm_distributor_id = 96  AND p.`is_balance` = 0 GROUP BY  DATE_FORMAT(p.create_time, '%Y-%m')) temp
		
		StringBuffer sql = new StringBuffer("SELECT COUNT(1) FROM (SELECT 1 FROM  c_order o INNER JOIN c_order_payment p  ON o.id = p.order_id  WHERE  1 = 1 ");
		
		sql = buildSql(sql, order);
		
		sql.append(" AND p.`is_balance` = 0) temp");
		Query query = em.createNativeQuery(sql.toString());
		return new Long(query.getSingleResult().toString()).longValue();
	}

	private StringBuffer buildSql(StringBuffer sql, COrder order){
		if(order.getDistributorId() != null){
			sql.append(" and o.distributor_id = ").append(order.getDistributorId());
		}
		
		if(order.getRecommDistributorId() != null){
			sql.append(" and o.recomm_distributor_id = ").append(order.getRecommDistributorId());
		}

		if(StringUtils.hasText(order.getBeginDate())){
			sql.append(" and p.create_time >= '").append(order.getBeginDate()).append("'");
		}
		
		if(StringUtils.hasText(order.getEndDate())){
			sql.append(" and o.create_time <= '").append(order.getEndDate()).append("'");
		}
		return sql;
	}
	
	@Override
	public Page<Object[]> findKValueList(COrder order, Pageable pageable) {
		//SELECT DATE_FORMAT(p.create_time, '%Y-%m') , SUM(p.`recomm_distributor_rebate`) FROM  c_order o INNER JOIN c_order_payment p ON o.id = p.order_id WHERE distributor_id = 100 AND recomm_distributor_id = 96 AND p.is_balance = 0 GROUP BY o.`distributor_name`,		  DATE_FORMAT(p.create_time, '%Y-%m')		ORDER BY DATE_FORMAT(p.create_time, '%Y-%m') DESC
		
		StringBuffer sql = new StringBuffer("SELECT o.`distributor_name`, DATE_FORMAT(p.create_time, '%Y-%m-%d') , p.`recomm_distributor_rebate` FROM  c_order o INNER JOIN c_order_payment p ON o.id = p.order_id WHERE 1 = 1 ");
		sql = buildSql(sql, order);
		sql.append(" AND p.is_balance = 0 ORDER BY DATE_FORMAT(p.create_time, '%Y-%m-%d') DESC");
		Query query = em.createNativeQuery(sql.toString());
		query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
		query.setMaxResults(pageable.getPageSize());
		return new PageImpl<Object[]>(query.getResultList(), pageable, total(order));
	}

	@Override
	public BigDecimal findKValue(Integer distributorId, String beginTime,
			String endTime, String day, String isBalance) {
		//StringBuffer sql = new StringBuffer(" SELECT IF(NULL, ROUND(SUM(balanceKValue), 2), 0) FROM (SELECT SUM(p.distributor_rebate) AS balanceKValue FROM c_order c INNER JOIN c_order_payment p ON c.id = p.order_id WHERE 1 = 1");
		//StringBuffer sql2 = new StringBuffer(" UNION SELECT SUM(p.recomm_distributor_rebate) AS balanceKValue FROM c_order c INNER JOIN c_order_payment p ON c.id = p.order_id WHERE 1 =1 ");
		
		StringBuffer sql = new StringBuffer("SELECT IFNULL(ROUND(SUM(p.distributor_rebate), 0), 0) AS balanceKValue FROM c_order c INNER JOIN c_order_payment p ON c.id = p.order_id WHERE 1 = 1");
		
		if(distributorId != null){
			sql.append(" and c.distributor_id = ").append(distributorId);
			//sql2.append(" and c.distributor_id = ").append(distributorId);
		}
		
		/*if(beginTime != null){
			sql.append(" and p.create_time >= '").append(beginTime).append("'");
			//sql2.append(" and p.create_time >= '").append(beginTime).append("'");
		}
		
		if(endTime != null){
			sql.append(" and p.create_time <= '").append(endTime).append("'");
			//sql2.append(" and p.create_time <= '").append(endTime).append("'");
		}*/
		
		if(day != null){
			sql.append(" and DATE_FORMAT(p.create_time, '%Y-%m-%d') = '").append(day).append("'");
			//sql2.append(" and p.create_time <= '").append(endTime).append("'");
		}
		
//		WHERE c.distributor_id = 1 AND p.is_balance = '0' AND p.create_time &gt;= AND p.create_time &lt;=
		if(StringUtils.hasText(isBalance)){
			sql.append(" and p.is_balance = '").append(isBalance).append("'");
			//sql2.append(" and p.is_balance = '").append(isBalance).append("'");
		}
		
		//WHERE c.distributor_id = 1 AND p.is_balance = '0' UNION SELECT SUM(p.recomm_distributor_rebate) AS balanceKValue FROM c_order c INNER JOIN c_order_payment p ON c.id = p.order_id WHERE c.distributor_id = 1 AND p.is_balance = '0') temp
		//sql2.append(") temp");
		//sql.append(sql2);
		Query query = em.createNativeQuery(sql.toString());
		Object result = query.getSingleResult();
		return result == null ? BigDecimal.ZERO : new BigDecimal(result.toString());
	}

	@Override
	public List<Object[]> findRecommKvalue(Integer distributorId) {
		return repository.findRecommKvalue(distributorId);
	}
}
